#include "gtest/gtest.h"
#include "TDBase.h"

class Test_PathRecyclePool : public ::testing::Test 
{
protected:
	void InitMap(StageMap& map) 
	{
		map.Clear();

		//	+--+--+--+--+
		//	| 0| 1| 2| 3|
		//	+--+--+--+--+  +--+
		//	| 4|  | 5| 6|  | 7|
		//	+--+  +--+--+  +--+

		map.Append(MapBrick(0,vector3di( 0,0,4),0,false,true,-1, 1, 4,-1));
		map.Append(MapBrick(0,vector3di( 2,0,4),0,false,true,-1, 2,-1, 0));
		map.Append(MapBrick(0,vector3di( 4,0,4),0,false,true,-1, 3, 5, 1));
		map.Append(MapBrick(0,vector3di( 6,0,4),0,false,true,-1,-1, 6, 2));
		map.Append(MapBrick(0,vector3di( 0,0,2),0,false,true, 0,-1,-1,-1));
		map.Append(MapBrick(0,vector3di( 4,0,2),0,false,true, 2, 6,-1,-1));
		map.Append(MapBrick(0,vector3di( 6,0,2),0,false,true,-1,-1, 5, 3));
		map.Append(MapBrick(0,vector3di(10,0,2),0,false,true,-1,-1,-1,-1));
	}
};

TEST_F (Test_PathRecyclePool, Follow)
{
	StageMap map;
	InitMap(map); 
	PathRecyclePool pool;

	PathInfo info = pool.FindPath (map, 4,5);
	ASSERT_EQ(0, info.PathIdx);
	ASSERT_EQ(0, info.SegIdx);
	ASSERT_EQ(1, pool.Size());
	ASSERT_EQ(5, pool.At(info.PathIdx).Size());

	PathInfo info1 = pool.FindPath (map, 0,5);
	ASSERT_EQ(0, info1.PathIdx);
	ASSERT_EQ(1, info1.SegIdx);
	ASSERT_EQ(1, pool.Size());
	ASSERT_EQ(5, pool.At(info1.PathIdx).Size());

	PathInfo info2 = pool.FindPath (map, 4,2);
	ASSERT_EQ(1, info2.PathIdx);
	ASSERT_EQ(0, info2.SegIdx);
	ASSERT_EQ(2, pool.Size());
	ASSERT_EQ(4, pool.At(info2.PathIdx).Size());

	pool.ReleasePath(0);
	pool.ReleasePath(0);

	PathInfo info3 = pool.FindPath (map, 3,6);
	ASSERT_EQ(0, info3.PathIdx);
	ASSERT_EQ(0, info3.SegIdx);
	ASSERT_EQ(2, pool.Size());
	ASSERT_EQ(2, pool.At(info3.PathIdx).Size());
}

TEST_F (Test_PathRecyclePool, Performance)
{
	StageMap map;
	InitMap(map); 
	PathRecyclePool pool;

	for (int i=0; i<100; i++)
	{
		PathInfo info1 = pool.FindPath (map, 4,5);
		ASSERT_EQ(1, pool.Size());

		PathInfo info2 = pool.FindPath (map, 0,5);
		ASSERT_EQ(1, pool.Size());
		
		pool.ReleasePath(0);
		pool.ReleasePath(0);

		PathInfo info3 = pool.FindPath (map, 6,4);
		ASSERT_EQ(1, pool.Size());
		pool.ReleasePath(0);
	}
}